<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <button id="btn">点一下，玩一年</button>
    <script>
      <!--    -->
      //创建地图
      function Map() {
        this.width = 800;
        this.height = 400;
        this.position = "relative";
        this.bgColor = "#cccccc";
        this._map = null;
        this._idName = "map";
      }
      Map.prototype.init = function () {
        this._map = document.createElement("div");
        this._map.style.width = this.width + "px";
        this._map.style.height = this.height + "px";
        this._map.style.position = this.position;
        this._map.style.backgroundColor = this.bgColor;
        this._map.id = this._idName;

        document.body.appendChild(this._map);
      };

      //创建食物
      function Food() {
        this.width = 20;
        this.height = 20;
        this.position = "absolute";
        this.bgColor = "orange";
        this.oFood = null;
        this.x = 0;
        this.y = 0;
        this.map = document.getElementById("map");
      }
      Food.prototype.init = function () {
        if (this.oFood == null) {
          this.oFood = document.createElement("div");
          this.oFood.style.width = this.width + "px";
          this.oFood.style.height = this.height + "px";
          this.oFood.style.position = this.position;
          this.oFood.style.backgroundColor = this.bgColor;
          //    在地图添加食物
          this.map.appendChild(this.oFood);
        }
        //    将食物分布坐标轴栅格化
        this.x = Math.floor(Math.random() * 40);
        this.y = Math.floor(Math.random() * 20);
        this.oFood.style.left = this.x * 20 + "px";
        this.oFood.style.top = this.y * 20 + "px";
      };

      //创建贪吃蛇
      function Snake(food) {
        //传入food，food为局部变量
        this.width = 20;
        this.height = 20;
        this.position = "absolute";
        this.map = document.getElementById("map");
        this.direct = "right";
        this.num = 0;
        this.timer = null;
        //初始化蛇身
        this.body = [
          //[x,y,color,div]
          [3, 2, "red", null],
          [2, 2, "blue", null],
          [1, 2, "blue", null],
        ];
        this.food = food;
      }

      //功能函数封装
      Snake.prototype.run = function () {
        that = this;
        this.show();
        this.timer = setInterval(function () {
          that.move();
        }, 500);
        //    控制方向
        document.onkeydown = function (ev) {
          var ev = ev || event;
          that.setDirect(ev.keyCode);
        };
      };

      //显示蛇身
      Snake.prototype.show = function () {
        for (var i = 0; i < this.body.length; i++) {
          if (this.body[i][3] == null) {
            //判断蛇是否已经存在
            this.body[i][3] = document.createElement("div");
            this.body[i][3].style.width = this.width + "px";
            this.body[i][3].style.height = this.height + "px";
            this.body[i][3].style.backgroundColor = this.body[i][2];
            this.body[i][3].style.position = this.position;
            this.map.appendChild(this.body[i][3]);
          }
          this.body[i][3].style.left = this.body[i][0] * 20 + "px";
          this.body[i][3].style.top = this.body[i][1] * 20 + "px";
        }
      };

      //动态相关
      Snake.prototype.move = function () {
        //身体部分
        var len = this.body.length;
        for (var i = len - 1; i > 0; i--) {
          //倒循环
          this.body[i][0] = this.body[i - 1][0];
          this.body[i][1] = this.body[i - 1][1];
        }
        //头部控制
        switch (this.direct) {
          case "right":
            this.body[0][0] += 1;
            break;
          case "left":
            this.body[0][0] -= 1;
            break;
          case "up":
            this.body[0][1] -= 1;
            break;
          case "down":
            this.body[0][1] += 1;
            break;
        }

        //判断吃食物
        if (
          this.body[0][0] === this.food.x &&
          this.body[0][1] === this.food.y
        ) {
          //蛇身添加
          var len = this.body.length;
          var x = this.body[len - 1][0];
          var y = this.body[len - 1][1];
          this.body.push([x, y, "blue", null]);
          //分数相加
          this.num++;
          document.title = this.num;
          //刷新食物
          this.food.init();
        }

        //碰壁判断
        if (
          this.body[0][0] < 0 ||
          this.body[0][0] > 39 ||
          this.body[0][1] < 0 ||
          this.body[0][1] > 19
        ) {
          clearInterval(this.timer);
          alert("游戏结束");
          return; //防止this.show执行
        }
        //将新蛇身添加
        this.show();
      };

      Snake.prototype.setDirect = function (keyCode) {
        switch (keyCode) {
          case 40:
            this.direct = "down";
            break;
          case 38:
            this.direct = "up";
            break;
          case 37:
            this.direct = "left";
            break;
          case 39:
            this.direct = "right";
            break;
        }
      };

      var oBtn = document.getElementById("btn");
      oBtn.onclick = function () {
        var map = new Map();
        map.init();

        var food = new Food();
        food.init();

        var snake = new Snake(food); //Snake的方法里有food对象
        snake.run();
      };
    </script>
  </body>
</html>
